home *** CD-ROM | disk | FTP | other *** search
- // Figure 3 for "A Little CAD with C++"
- // Copyright 1988 Bruce Eckel
- // Permission required to distribute source
-
- // file: msmenu.cpp
- #include <stdio.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <msmouse.h>
- // flash graphics declarations:
- #include <fg.h>
- #include <string.h>
- #include "msmenu.hpp"
-
- msmenu::msmenu(struct menu_s * mp) {
- char buf[15];
- count = 0;
- // attach the menu pointer to this object:
- m = mp;
- // Store the size of the menu:
- height = 0;
- struct menu_s * mm = m;
- // look for end marker:
- while ( mm->item_number != -1) {
- height++;
- mm++;
- }
- int ss, i;
- for(i = 0, width = 0; i < height; i++)
- if ((ss = strlen(mp[i].name)) > width)
- // find the largest element:
- width = ss;
-
- // graphic width:
- xsize = width * CHARWIDTH;
- // graphic height:
- ysize = height * LINESIZE;
-
- sizing_box[FG_X1] = 0;
- sizing_box[FG_Y1] = 0;
- sizing_box[FG_X2] = xsize + LINESIZE;
- sizing_box[FG_Y2] = ysize + LINESIZE;
- msize = sizing_box[FG_X2]
- - sizing_box[FG_X1] + 1;
- msize *= sizing_box[FG_Y2]
- - sizing_box[FG_Y1] + 1;
- msize *= sizeof(fg_color_t);
- // allocate memory for graphics storage:
- color_p = new fg_color_t[msize];
- blank_p = new fg_color_t[msize];
- // save blank image of menu size:
- fg_readbox(sizing_box, blank_p);
- // initialize mouse:
- msm_init();
- // turn mouse cursor on:
- msm_showcursor();
- }
-
- msmenu::~msmenu() {
- delete color_p;
- delete blank_p;
- // turn mouse cursor off:
- msm_hidecursor();
- // terminate use of mouse:
- msm_term();
- }
-
- void msmenu::drawmenu(int x,int y) {
- struct menu_s * elem = m;
- for (int i = 0; i < height; i++) {
- fg_puts (FG_WHITE, FG_MODE_SET, ~0, FG_ROT0,
- x,y, elem->name, fg_displaybox);
- elem++;
- y -= LINESIZE;
- }
- }
-
- /* The following patterns were created from the
- commented block of ones and zeros using the
- tool MSCURSOR.CPP (Figure 13) */
-
- static int default_cur[] = {
- 0xffff, /* 0000000000000000 */
- 0xdfff, /* 0010000000000000 */
- 0xcfff, /* 0011000000000000 */
- 0xc7ff, /* 0011100000000000 */
- 0xc3ff, /* 0011110000000000 */
- 0xc1ff, /* 0011111000000000 */
- 0xc0ff, /* 0011111100000000 */
- 0xc07f, /* 0011111110000000 */
- 0xc03f, /* 0011111111000000 */
- 0xc01f, /* 0011111111100000 */
- 0xc1ff, /* 0011111000000000 */
- 0xdcff, /* 0010001100000000 */
- 0xfcff, /* 0000001100000000 */
- 0xfe7f, /* 0000000110000000 */
- 0xfe7f, /* 0000000110000000 */
- 0xffff, /* 0000000000000000 */
- 0x0, 0x2000, 0x3000, 0x3800, 0x3c00, 0x3e00,
- 0x3f00, 0x3f80, 0x3fc0, 0x3fe0, 0x3e00,
- 0x2300, 0x300, 0x180, 0x180, 0x0,
- };
-
- static int menu_cur[] = {
- 0xffff, /* 0000000000000000 */
- 0xffff, /* 0000000000000000 */
- 0xffff, /* 0000000000000000 */
- 0xffff, /* 0000000000000000 */
- 0xffef, /* 0000000000010000 */
- 0xdfe7, /* 0010000000011000 */
- 0x6fe3, /* 1001000000011100 */
- 0xb7e1, /* 0100100000011110 */
- 0xc000, /* 0011111111111111 */
- 0xb7e1, /* 0100100000011110 */
- 0x6fe3, /* 1001000000011100 */
- 0xdfe7, /* 0010000000011000 */
- 0xffef, /* 0000000000010000 */
- 0xffff, /* 0000000000000000 */
- 0xffff, /* 0000000000000000 */
- 0xffff, /* 0000000000000000 */
- 0x0, 0x0, 0x0, 0x0, 0x10, 0x2018,
- 0x901c, 0x481e, 0x3fff, 0x481e,
- 0x901c, 0x2018, 0x10, 0x0, 0x0, 0x0,
- };
-
- static int cross_cur[] = {
- 0xffff, /* 0000000000000000 */
- 0xffff, /* 0000000000000000 */
- 0xffff, /* 0000000000000000 */
- 0xfeff, /* 0000000100000000 */
- 0xfeff, /* 0000000100000000 */
- 0xfeff, /* 0000000100000000 */
- 0xfeff, /* 0000000100000000 */
- 0xfeff, /* 0000000100000000 */
- 0x0, /* 1111111111111111 */
- 0xfeff, /* 0000000100000000 */
- 0xfeff, /* 0000000100000000 */
- 0xfeff, /* 0000000100000000 */
- 0xfeff, /* 0000000100000000 */
- 0xffff, /* 0000000000000000 */
- 0xffff, /* 0000000000000000 */
- 0xffff, /* 0000000000000000 */
- 0x0, 0x0, 0x0, 0x100, 0x100, 0x100,
- 0x100, 0x100, 0xffff, 0x100, 0x100,
- 0x100, 0x100, 0x0, 0x0, 0x0,
- };
-
- /* the first two numbers are the x and y
- coordinates of the "hot spot", with the
- upper left corner = 0,0: */
-
- void msmenu::default_cursor() {
- msm_setgraphcur(-1,-1,default_cur);
- }
-
- void msmenu::menu_cursor() {
- msm_setgraphcur(-16,-8,menu_cur);
- }
-
- void msmenu::cross_cursor() {
- msm_setgraphcur(-8,-8,cross_cur);
- }
-
- int
- msmenu::get_selection(unsigned x, unsigned yy) {
- unsigned int u,v, startv;
- unsigned y = yy;
- fg_box_t read_box;
- translate_coords(&x,&y);
- read_box[FG_X1] = x;
- read_box[FG_Y1] = y - ysize + LINESIZE;
- read_box[FG_X2] = x + xsize;
- read_box[FG_Y2] = y + LINESIZE;
-
- msm_hidecursor();
- // use special cursor:
- menu_cursor();
- fg_readbox(read_box, color_p);
- // blank section out:
- fg_writebox(read_box, blank_p);
- // call a private function:
- drawmenu(x,y);
- // trial-and-error:
- msm_setcurpos(x - 35 , yy -22);
- msm_showcursor();
- msm_setareax(x -35, x - 35);
- msm_setareay(yy - 22,
- yy - 22 + ysize - LINESIZE );
- startv = yy - 22;
- wait_left_pressed(&u,&v);
- wait_left_released(&u,&v);
-
- // put everything back the way it was:
- msm_setareax(fg_displaybox[FG_X1],
- fg_displaybox[FG_X2]);
- msm_setareay(fg_displaybox[FG_Y1],
- fg_displaybox[FG_Y2]);
- msm_hidecursor();
- // Restore old cursor:
- default_cursor();
- // restore original position:
- msm_setcurpos(x, yy);
- // restore screen:
- fg_writebox(read_box, color_p);
- msm_showcursor();
- // calculate which item was selected:
- return m[(v - startv)/LINESIZE].item_number;
- }
-